package com.pig4cloud.pigx.common.websocket.subscribe;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.pig4cloud.pigx.common.core.util.SpringContextHolder;
import com.pig4cloud.pigx.common.websocket.subscribe.handler.WebSocketSubscribeHandler;
import com.pig4cloud.pigx.common.websocket.subscribe.message.BaseSubscribeMessage;
import com.pig4cloud.pigx.common.websocket.vo.WebSocketRes;
import lombok.AllArgsConstructor;
import org.apache.logging.log4j.util.Strings;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.Map;
import java.util.Objects;

/**
 * webSocket订阅管理器 todo 后续迭代
 *
 * @date 2022/8/27 21:08
 */
@Component
@AllArgsConstructor
public class WebSocketSubscribeManager {
	/**
	 * 订阅前缀
	 */
	public static final String TYPE_PREFIX = "subscribe@";
	/**
	 * webSocket订阅处理器
	 */
	private static final Map<String, WebSocketSubscribeHandler> HANDLER_LIST = SpringContextHolder.getBeansOfType(WebSocketSubscribeHandler.class);

	private final ObjectMapper objectMapper;

	/**
	 * 处理消息
	 *
	 * @param payLoad 消息
	 * @date 2022/8/27 21:41
	 */
	public WebSocketRes handlerMsg(String payLoad) throws Exception {
		BaseSubscribeMessage<?> message = objectMapper.readValue(payLoad, BaseSubscribeMessage.class);
		String type = message.getType();

		// 初步校验参数
		validMsg(message);

		message.getStreamNameList().forEach(streamName -> {
			// 寻找对应的
			for (WebSocketSubscribeHandler<?> handler : HANDLER_LIST.values()) {
				if (!handler.support(streamName)) {
					continue;
				}


				break;
			}
		});

		return null;
	}

	/**
	 * 初步校验参数
	 *
	 * @param message 消息
	 * @date 2022/8/27 21:47
	 */
	private void validMsg(BaseSubscribeMessage message) {
		if (Objects.isNull(message)) {
			throw new RuntimeException("message not found");
		}

		if (Strings.isEmpty(message.getType())) {
			throw new RuntimeException("type can not be null");
		}

		if (CollectionUtils.isEmpty(message.getStreamNameList())) {
			throw new RuntimeException("streamNameList can not be empty, at least one parameter is required");
		}

		if (message.isSetProperty()) {
			if (Objects.isNull(message.getData())) {
				throw new RuntimeException("data can not be null");
			}
		}
	}
}
